package com.greensecurity.sim.controller;

import com.greensecurity.sim.entity.Role;
import com.greensecurity.sim.entity.User;
import com.greensecurity.sim.service.UserService;
import com.greensecurity.sim.shiro.ResponseObject;
import com.greensecurity.sim.util.SplitUser;
import com.greensecurity.sim.util.ValidatorUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.session.Session;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

@Controller
@Slf4j
@RequestMapping("/login")
@Api(value = "登录管理")
public class LoginController {

    @Resource
    private UserService userService;

    @ApiOperation(value = "登录")
    @GetMapping( "/login")
    public String login() {
        return "login";
    }

    @ResponseBody
    @ApiOperation(value = "登录验证码获取")
    @GetMapping( "/code/{phone}")
    public String code(HttpServletRequest httpRequest,@PathVariable String phone) {
        User user= userService.findByPhone(phone);
        if (user==null){
            throw new RuntimeException("用户未注册");
        }
        String code = String.valueOf(Math.round((Math.random()+1) * 1000));
        HttpSession session =httpRequest.getSession();
        session.setAttribute("loginCode",code);
        return code;
    }

    @ResponseBody
    @ApiOperation(value = "提交登录用户名密码")
    @PostMapping( "/submit")
    public ResponseObject loginSubmit(@RequestBody User user,HttpServletRequest httpServletRequest) {
        HttpSession httpSession = httpServletRequest.getSession();
        ResponseObject responseObject = new ResponseObject();
//        如果没有传入验证码，就去验证密码
        if (!Objects.equals(null, user.getUserId())){
            String code =  httpSession.getAttribute("loginCode").toString();
            if (Objects.equals(code, String.valueOf(user.getUserId()))){
                User codeUser= userService.findByPhone(user.getPhone());
                user.setPassword(codeUser.getPassword());
            }else{
                throw new RuntimeException("手机号不正确");
            }
        }else {
            if (StringUtils.isEmpty(user.getPhone()) || StringUtils.isEmpty(user.getPassword())) {
                responseObject.failed(400,"请输入手机号和密码！");
                return responseObject;
            }
            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        }
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        //shiro认证
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                user.getPhone(),
                user.getPassword()
        );
        try {
            //进行验证，这里可以捕获异常，然后返回对应信息
            subject.login(usernamePasswordToken);
            Session session = subject.getSession();
//            发送sessionId
            String sessionId = (String) session.getId();
            responseObject.success(200,sessionId);
//            调用权限添加
            Boolean isP=  subject.isPermitted("query");
        } catch (UnknownAccountException e) {
            responseObject.failed(400,"用户名不存在！");
            throw new RuntimeException("用户名不存在");
        } catch (AuthenticationException e) {
            responseObject.failed(400,"账号或密码错误！");
            throw new RuntimeException("账号或者密码错误");

        } catch (AuthorizationException e) {
            responseObject.failed(401,"没有权限！");
            throw new RuntimeException("没有权限");
        }
        return responseObject;
    }

    @ApiOperation(value = "web登录方法，跳转页面")
    @PostMapping( "/webLogin")
    public String webLogin(@RequestBody User user) {
        if (StringUtils.isEmpty(user.getPhone()) || StringUtils.isEmpty(user.getPassword())) {
            throw  new RuntimeException("请输入手机号和密码！");
        }
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        String passwordMd5 = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        //shiro认证
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                user.getPhone(),
                passwordMd5
        );
        try {
            //进行验证，这里可以捕获异常，然后返回对应信息
            subject.login(usernamePasswordToken);
//            调用权限添加
            Boolean isP=  subject.isPermitted("query");
        } catch (UnknownAccountException e) {
            throw new RuntimeException("用户名不存在");
        } catch (AuthenticationException e) {
            throw new RuntimeException("账号或者密码错误");
        } catch (AuthorizationException e) {
            throw new RuntimeException("错误:"+e.getMessage());
        }
        return "redirect:/swagger-ui.html";
    }


    @ApiOperation(value = "admin权限验证")
//    @RequiresRoles("admin")
    @GetMapping("/admin")
    public String admin() {
        return "redirect:/swagger-ui.html";
    }

    @ResponseBody
    @ApiOperation(value = "首页跳转")
    @GetMapping("/home")
    public User index() {
        User user= userService.findByPhone("13065162873");
        SplitUser.splitUser(user);
        return user;
    }


    @ResponseBody
    @ApiOperation(value = "错误跳转")
    @GetMapping("/error")
    public String error() {
        return "error";
    }


    @ApiOperation(value = "add权限验证")
    @ResponseBody
    @RequiresPermissions("query")
    @GetMapping("/add/{id}")
    public String add(@PathVariable String id) {
        log.info(String.valueOf(userService.findByPhone(id)));
        return "add success!";
    }


    @ResponseBody
    @ApiOperation(value = "登出")
    @GetMapping("/logout")
    public String defaultLoginOut() {
        // 从SecurityUtils里边创建一个 subject
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "退出登录成功";
    }

    @ApiOperation(value = "注册")
    @ResponseBody
    @PostMapping("/register")
    public User registerUser(@RequestBody User user){
        try {
            User isRegister = userService.findByPhone(user.getPhone());
            if (isRegister != null){
                throw new RuntimeException("手机号已存在");
            }
            if (! ValidatorUtils.isMobile(user.getPhone())){
                throw new RuntimeException("手机号格式不正确");
            }
            if (! ValidatorUtils.isPassword(user.getPassword())){
                throw new RuntimeException("用户密码格式不正确，密码至少6位，最多16位，包含大小写字母和数字");
            }
//            密码加密
            String passwordMd5 = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
            user.setPassword(passwordMd5);
            user.setUserId(Long.valueOf(1));
            user.setCreateTime(new Date());
            user.setUserName("用户"+user.getPhone());
            user.setRealName("用户"+user.getPhone());
//            用户权限默认为 user
            List<Role> role = new ArrayList<>();
            Role addRole = new Role();
            addRole.setRoleName("user");
            addRole.setId(Long.valueOf(2));
            role.add(addRole);
            user.setRole(role);
            userService.save(user);
            return user;
        }catch (Exception e){
            log.error(String.valueOf(e));
            throw new RuntimeException("新增用户失败:"+e.getMessage());
        }
    }
}
